<template>
  <div class="novel-container">
    <div class="novel-main-title-box">
      <div v-show="hideShowBtn" class="novel-main-title">神秘复苏</div>
      <div class="options-box">
        <div v-show="hideShowBtn" class="speech-rate-select-box">
          <span>播放语速：</span>
          <el-select v-model="speechRate">
            <el-option :value="1">1</el-option>
            <el-option :value="1.5">1.5</el-option>
            <el-option :value="2">2</el-option>
            <el-option :value="3">3</el-option>
            <el-option :value="4">4</el-option>
            <el-option :value="5">5</el-option>
          </el-select>
        </div>
        <el-button v-show="hideShowBtn" type="primary" @click="startSpeechNovel">从当前页开始播放</el-button>
        <el-button v-show="hideShowBtn" type="danger" @click="stopSpeechNovel">停止播放</el-button>
        <el-button v-show="hideShowBtn" type="warning" v-if="isPause" @click="pauseSpeechNovel">暂停播放</el-button>
        <el-button v-show="hideShowBtn" type="success" v-else @click="resumeSpeechNovel">继续播放</el-button>
        <el-button type="info" @click="hideShowBtn = !hideShowBtn">???</el-button>
      </div>
    </div>
    <div class="novel-content-box">
      <div v-if="isLoad" class="novel-content">
        <Loading></Loading>
      </div>
      <div v-else class="novel-content" v-html="showTxtCentent"></div>
    </div>
    <div v-show="hideShowBtn" class="novel-footer-box">
      <h5>
        当前页：第{{ currentPageIndex + 1 }}页&nbsp;&nbsp;&nbsp;最大页数：{{
          Math.ceil(allTxtContent.length / chunkSize)
        }}页
      </h5>
      <div class="btn-box">
        <el-button type="primary" @click="changeLastPage">上一页</el-button>
        <el-button type="primary" @click="changeNextPage">下一页</el-button>
        <div class="jump-box">
          <div class="text">跳转到</div>
          <el-input v-model="wantJumpPage" />
          <div class="text">页</div>
          <el-button type="primary" @click="jumpPage">跳转</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ElMessage } from "element-plus"
import axios from "axios"

let allTxtContent = ""
const lastTxtContent = ref("")
const nextTxtContentChunk = ref("")
const chunkSize = 500 // 每次加载的字符数
let currentChunkStart = 0 // 当前截取内容的起始位置
let currentChunkEnd = currentChunkStart + chunkSize // 当前截取内容的结束位置
const currentPageIndex = ref(0) // 当前页索引
const wantJumpPage = ref(1)
const isPause = ref(true)
const isLoad = ref(true)
const speechRate = ref(1.5)
const hideShowBtn = ref(true)

// 显示当前页内容
const showTxtCentent = computed(() => `${nextTxtContentChunk.value}`.replace(/\n/g, "<br/>").replace(/\r/g, "&nbsp;"))

const getTxtContent = () => {
  axios
    .get("/static/txt/神秘复苏.txt", {
      responseType: "text",
    })
    .then((res) => {
      allTxtContent = res.data
      loadRememberRead()
      if (currentPageIndex.value === 0) {
        loadMore()
      }
      isLoad.value = false
    })
    .catch((error) => {
      console.error(error)
    })
}

// 加载一页内容
const loadMore = () => {
  console.log(currentChunkStart, currentChunkEnd)
  if (currentChunkStart >= allTxtContent.length) {
    console.log("所有内容已加载")
    return
  }
  rememberCurrentRead()
  nextTxtContentChunk.value = allTxtContent.substring(currentChunkStart, currentChunkEnd)
  lastTxtContent.value = `${lastTxtContent.value}${nextTxtContentChunk.value}`
  // console.log("lastTxtContent", lastTxtContent)
}

const changeLastPage = () => {
  if (currentPageIndex.value < 1) {
    console.warn("已经是第一页")
    return
  }
  currentPageIndex.value = currentPageIndex.value - 1
  currentChunkStart = currentPageIndex.value * chunkSize
  currentChunkEnd = currentChunkStart + chunkSize
  wantJumpPage.value = currentPageIndex.value + 1
  loadMore()
}
const changeNextPage = () => {
  if (wantJumpPage.value * chunkSize >= allTxtContent.length) {
    console.warn("已经是最后一页")
    return
  }
  currentPageIndex.value = currentPageIndex.value + 1
  currentChunkStart = currentPageIndex.value * chunkSize
  currentChunkEnd = currentChunkStart + chunkSize
  wantJumpPage.value = currentPageIndex.value + 1
  loadMore()
}
const jumpPage = () => {
  const pageNum = Number(wantJumpPage.value)
  if (typeof pageNum !== "number" || Number.isNaN(pageNum)) {
    alert("非法数字")
    return
  }
  wantJumpPage.value = Math.floor(wantJumpPage.value)
  currentPageIndex.value = wantJumpPage.value - 1
  if (currentPageIndex.value < 1) {
    currentPageIndex.value = 0
    wantJumpPage.value = currentPageIndex.value + 1
  }
  if (currentPageIndex.value * chunkSize >= allTxtContent.length) {
    currentPageIndex.value = Math.floor(allTxtContent.length / chunkSize)
    wantJumpPage.value = currentPageIndex.value + 1
  }
  currentChunkStart = currentPageIndex.value * chunkSize
  currentChunkEnd = currentChunkStart + chunkSize
  console.log("currentPageIndex.value", currentPageIndex.value)
  loadMore()
}

const synth = window.speechSynthesis
const speech = new SpeechSynthesisUtterance()
synth.onvoiceschanged = (event) => {
  console.log("event", event.target)
}
const startSpeechNovel = () => {
  // const speechText = showTxtCentent.value.replace(/&nbsp/g, "").replace(/<br\/>/g, "")
  // const speech = new SpeechSynthesisUtterance(speechText)
  // 播放完的回调
  speech.onend = (event) => {
    // console.log("播完event", event)
    changeNextPage()
    startSpeechNovel()
  }
  // console.log("synth", synth)
  // console.log("speech", speech)
  if (synth.speaking || synth.paused) {
    stopSpeechNovel()
  }
  const speechText = showTxtCentent.value.replace(/&nbsp/g, "").replace(/<br\/>/g, "")
  speech.text = speechText // 播放文本
  speech.rate = speechRate.value || 1.5 // 播放语速。默认值1，区间[0.1,10]
  speech.pitch = 1.2 // 音调高低。默认值1，区间[0,2]
  speech.volume = 1 // 播放音量。默认值1，区间[0,1]
  speech.lang = "zh-CN" // 设置播放语言。zh-CN：中文
  synth.speak(speech)
}
const stopSpeechNovel = () => {
  synth.cancel()
  isPause.value = true
}
const pauseSpeechNovel = () => {
  synth.pause()
  isPause.value = false
}
const resumeSpeechNovel = () => {
  synth.resume()
  isPause.value = true
}

// 记录当前阅读的页
const rememberCurrentRead = () => {
  localStorage.setItem("currentPageIndex", `${currentPageIndex.value}`)
}
// 加载上次阅读位置
const loadRememberRead = () => {
  try {
    const rememberReadIndex = Number(localStorage.getItem("currentPageIndex") || 0)
    // console.log("rememberReadIndex", rememberReadIndex)
    if (rememberReadIndex) {
      console.log("rememberReadIndex 存在，开始加载", rememberReadIndex)
      currentPageIndex.value = Number(rememberReadIndex)
      wantJumpPage.value = currentPageIndex.value + 1
      jumpPage()
      ElMessage.success("已加载至上次阅读位置")
      console.log("已加载至上次阅读位置")
    }
  } catch (error) {
    console.error("error", error)
  }
}

getTxtContent()
</script>

<style lang="scss" scoped>
.novel-container {
  background-color: #000000;
  color: #414141;
  width: 100%;
  height: 100vh;
  padding: 10px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: space-between;

  .novel-main-title-box {
    text-align: center;
    .novel-main-title {
      font-weight: 700;
      font-size: 20px;
    }
    .options-box {
      padding: 4px 0;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
      .speech-rate-select-box {
        margin-right: 12px;
        .el-select {
          width: 80px;
        }
      }
    }
  }
  .novel-content-box {
    height: 82vh;
    padding: 10px;
    box-sizing: border-box;
    overflow: auto;
    .novel-content {
      width: 100%;
      height: 100%;
    }
  }
  .novel-footer-box {
    .btn-box {
      display: flex;
      align-items: center;

      .jump-box {
        margin: 0 10px;
        display: flex;
        justify-content: center;
        align-items: center;

        .text {
          padding: 0 4px;
          box-sizing: border-box;
        }

        .el-input {
          width: 100px;
        }
      }
    }
  }
}
</style>
